package com.security.demo.config;

import com.security.demo.handel.CustomAccessDeniedHandler;
import com.security.demo.handel.CustomAuthenticationFailureHandler;
import com.security.demo.handel.CustomAuthenticationSuccessHandler;
import com.security.demo.service.Impl.UserServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.logout.HttpStatusReturningLogoutSuccessHandler;

/**
 * 配置security
 */
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Value("${spring.security.loginPage}")
    private String loginPage;

    @Autowired
    private CustomAuthenticationSuccessHandler customAuthenticationSuccessHandler;

    @Autowired
    private CustomAuthenticationFailureHandler customAuthenticationFailureHandler;

    @Autowired
    private CustomAccessDeniedHandler customAccessDeniedHandler;

    @Autowired
    private UserServiceImpl userServiceImpl;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // 添加请求授权规则
        http.authorizeRequests()
                // 首页所有人都可以访问
                .antMatchers("/public/**").permitAll()
                // user下的所有请求，user角色权限才能访问
                .antMatchers("/user/**").hasRole("USER")
                // admin下的所有请求，ADMIN角色权限才能访问
                .antMatchers("/admin/**").hasRole("ADMIN")
                // 其他任何请求都要验证身份
                .anyRequest().authenticated();
        // 开启登录页面，即没有权限的话跳转到登录页面
        http.formLogin()
                // 登录页面
                .loginPage(loginPage)
                // 用户名的name
                .usernameParameter("user")
                // 密码的name
                .passwordParameter("pwd")
                // 处理登录的Controller
                .loginProcessingUrl("/login")
                // 验证成功处理器
                .successHandler(customAuthenticationSuccessHandler)
                // 验证失败处理器
                .failureHandler(customAuthenticationFailureHandler);
        http.csrf().disable();
        // 开启记住我功能，默认保存两周
        http.rememberMe()
                // name属性
                .rememberMeParameter("remember");
        // 开启退出登录功能
        http.logout()
                .logoutUrl("/logout")
                .logoutSuccessHandler(new HttpStatusReturningLogoutSuccessHandler(HttpStatus.OK)); // 自定义登出成功后的处理
        // 跨域
        http.cors();
        // 权限不足处理器
        http.exceptionHandling().accessDeniedHandler(customAccessDeniedHandler);
    }

    // 认证规则
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        // 在新版本的SpringSecurity中新增了许多加密方法，这里使用的是BCrypt
        auth.userDetailsService(userServiceImpl).passwordEncoder(new BCryptPasswordEncoder());
    }

}
